package com.probiz.estore.order.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;

import com.probiz.estore.Constants;
import com.probiz.estore.common.model.cart.Shoppingcart;
import com.probiz.estore.common.model.cart.ShoppingcartItem;
import com.probiz.estore.common.model.cart.ShoppingcartItemGc;
import com.probiz.estore.common.model.cart.ShoppingcartPromotion;
import com.probiz.estore.common.model.customer.Customer;
import com.probiz.estore.common.model.customer.ShopPoint;
import com.probiz.estore.common.model.order.CheckoutSession;
import com.probiz.estore.common.model.order.OrderAddress;
import com.probiz.estore.common.model.order.OrderPayment;
import com.probiz.estore.common.model.order.OrderPick;
import com.probiz.estore.common.model.order.OrderPickItem;
import com.probiz.estore.common.model.order.OrderPromotion;
import com.probiz.estore.common.model.order.OrderShipment;
import com.probiz.estore.common.model.order.OrderShipmentItem;
import com.probiz.estore.common.model.order.OrderSku;
import com.probiz.estore.common.model.order.SalesOrder;
import com.probiz.estore.common.model.sales.Gift;
import com.probiz.estore.common.model.sales.PromoRule;
import com.probiz.estore.common.model.system.PaymentMethod;
import com.probiz.estore.common.model.system.Region;
import com.probiz.estore.common.model.system.SelfCollectionCentre;
import com.probiz.estore.common.model.system.ShippingMethod;
import com.probiz.estore.common.model.system.ShippingRate;
import com.probiz.estore.common.service.CustomerService;
import com.probiz.estore.common.service.GiftCertificateService;
import com.probiz.estore.common.service.ProductService;
import com.probiz.estore.common.service.PromoService;
import com.probiz.estore.common.service.RecommendedService;
import com.probiz.estore.common.util.NumberUtil;
import com.probiz.estore.core.util.ContextUtil;
import com.probiz.estore.customer.service.CustomerManager;
import com.probiz.estore.customer.service.ShopPointManager;
import com.probiz.estore.exception.GiftCertificateStateException;
import com.probiz.estore.exception.OrderProccessFlowException;
import com.probiz.estore.exception.OutOfStockException;
import com.probiz.estore.exception.ShopPointConsumptionException;
import com.probiz.estore.exception.UnderMinimumPurchaseQuantityException;
import com.probiz.estore.inventory.InventoryConstants;
import com.probiz.estore.inventory.service.InventoryManager;
import com.probiz.estore.order.OrderConstants;
import com.probiz.estore.order.model.OrderCancelModel;
import com.probiz.estore.order.model.OrderCompleteModel;
import com.probiz.estore.order.service.OrderAddressManager;
import com.probiz.estore.order.service.OrderAuditHelper;
import com.probiz.estore.order.service.OrderPaymentManager;
import com.probiz.estore.order.service.OrderPickItemManager;
import com.probiz.estore.order.service.OrderPickManager;
import com.probiz.estore.order.service.OrderProcessFlowManager;
import com.probiz.estore.order.service.OrderPromotionManager;
import com.probiz.estore.order.service.OrderShipmentItemManager;
import com.probiz.estore.order.service.OrderShipmentManager;
import com.probiz.estore.order.service.OrderSkuManager;
import com.probiz.estore.order.service.SalesOrderManager;
import com.probiz.estore.order.util.OrderCodeGenerator;
import com.probiz.estore.sales.model.EmailModel;
import com.probiz.estore.sales.service.GiftCertificateManager;
import com.probiz.estore.sales.service.GiftManager;
import com.probiz.estore.sales.service.PromoRuleManager;
import com.probiz.estore.system.service.MsgSendManager;
import com.probiz.estore.system.service.PaymentMethodManager;
import com.probiz.estore.system.service.RegionManager;
import com.probiz.estore.system.service.SelfCollectionCentreManager;
import com.probiz.estore.system.service.ShippingRateManager;
import com.probiz.estore.system.util.MsgTemplateConstants;
import com.probiz.estore.webapp.util.RequestContext;
import com.probiz.estore.webapp.util.RequestUtil;

public class OrderProcessFlowManagerImpl implements OrderProcessFlowManager, InitializingBean {
	private SalesOrderManager salesOrderManager;
	
	private OrderPromotionManager  orderPromotionManager ;
	
	private OrderSkuManager orderSkuManager ;
	
	private OrderAddressManager orderAddressManager ;
	
	private OrderPaymentManager orderPaymentManager ;
	
	private OrderShipmentManager orderShipmentManager ;
	
	private OrderShipmentItemManager orderShipmentItemManager;
	
	private OrderPickManager orderPickManager;
	
	private OrderPickItemManager orderPickItemManager;
	
	private PaymentMethodManager paymentMethodManager ;
	
	private ShippingRateManager shippingRateManager;
	
	private SelfCollectionCentreManager selfCollectionCentreManager;
	
	private OrderAuditHelper orderAuditHelper ;
	
	private ShopPointManager shopPointManager ;
	
	private CustomerManager customerManager ;
	
	private GiftCertificateManager giftCertificateManager  ;
	
	private GiftCertificateService giftCertificateService ;
	
	private InventoryManager inventoryManager ;
	
	private CustomerService customerService;
	
	private ProductService productService;
	
	private RegionManager regionManager ;
	
	private RecommendedService recommendedService;
	
	private MsgSendManager msgSendManager;
	
	private GiftManager giftManager;
	
	private PromoRuleManager promoRuleManager;
	
	public void setPromoRuleManager(PromoRuleManager promoRuleManager) {
		this.promoRuleManager = promoRuleManager;
	}

	public void setGiftManager(GiftManager giftManager) {
		this.giftManager = giftManager;
	}

	public void setMsgSendManager(MsgSendManager msgSendManager) {
		this.msgSendManager = msgSendManager;
	}

	public void setOrderPromotionManager(OrderPromotionManager orderPromotionManager) {
		this.orderPromotionManager = orderPromotionManager;
	}

	public void setOrderSkuManager(OrderSkuManager orderSkuManager) {
		this.orderSkuManager = orderSkuManager;
	}

	
	public void setOrderAddressManager(OrderAddressManager orderAddressManager) {
		this.orderAddressManager = orderAddressManager;
	}

	
	public void setOrderPaymentManager(OrderPaymentManager orderPaymentManager) {
		this.orderPaymentManager = orderPaymentManager;
	}
	
	

	public void setOrderShipmentManager(OrderShipmentManager orderShipmentManager) {
		this.orderShipmentManager = orderShipmentManager;
	}
	
	

	public void setOrderShipmentItemManager(OrderShipmentItemManager orderShipmentItemManager) {
		this.orderShipmentItemManager = orderShipmentItemManager;
	}
	

	public void setOrderPickManager(OrderPickManager orderPickManager) {
		this.orderPickManager = orderPickManager;
	}
	

	public void setOrderPickItemManager(OrderPickItemManager orderPickItemManager) {
		this.orderPickItemManager = orderPickItemManager;
	}

	public void setPaymentMethodManager(PaymentMethodManager paymentMethodManager) {
		this.paymentMethodManager = paymentMethodManager;
	}
	

	public void setShippingRateManager(ShippingRateManager shippingRateManager) {
		this.shippingRateManager = shippingRateManager;
	}

	public void setSelfCollectionCentreManager(SelfCollectionCentreManager selfCollectionCentreManager) {
		this.selfCollectionCentreManager = selfCollectionCentreManager;
	}

	private String getMessage(String key, Object... params){
		return ContextUtil.getSpringContext().getMessage(key, params, null);
	}
	

	public void setSalesOrderManager(SalesOrderManager salesOrderManager) {
		this.salesOrderManager = salesOrderManager;
	}

	public void setOrderAuditHelper(OrderAuditHelper orderAuditHelper) {
		this.orderAuditHelper = orderAuditHelper;
	}

	public void setShopPointManager(ShopPointManager shopPointManager) {
		this.shopPointManager = shopPointManager;
	}

	public void setCustomerManager(CustomerManager customerManager) {
		this.customerManager = customerManager;
	}

	public void setGiftCertificateManager(
			GiftCertificateManager giftCertificateManager) {
		this.giftCertificateManager = giftCertificateManager;
	}

	public void setGiftCertificateService(
			GiftCertificateService giftCertificateService) {
		this.giftCertificateService = giftCertificateService;
	}

	public void setInventoryManager(InventoryManager inventoryManager) {
		this.inventoryManager = inventoryManager;
	}


	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}
	

	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	public PromoService getPromoService(){
		return (PromoService)ContextUtil.getSpringBeanById("promoService");
	}
	
	
	public void setRegionManager(RegionManager regionManager) {
		this.regionManager = regionManager;
	}


	public void setRecommendedService(RecommendedService recommendedService) {
		this.recommendedService = recommendedService;
	}

	public void afterPropertiesSet() throws Exception {
		
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#createSalesOrder(com.probiz.estore.common.model.order.CheckoutSession)
	 */
	public SalesOrder createSalesOrder(CheckoutSession checkoutSession) throws OutOfStockException, GiftCertificateStateException, ShopPointConsumptionException{
		//----------------创建订单主体对像，包括送货地址----------------
		SalesOrder salesOrder = checkoutSession.generateSalesOrder();
		if(null != salesOrder.getOrderAddress()){
			orderAddressManager.save(salesOrder.getOrderAddress());
		}
		
		//----------------其他----------------
		if(RequestContext.isFront()){
			salesOrder.setOrderSource(OrderConstants.SOURCE_CUSTOMER);
		}else{
			salesOrder.setOrderSource(OrderConstants.SOURCE_ADMIN);
		}
		salesOrder.setIsPrinted(Constants.FLAG_FALSE);
		salesOrder.setIpAddress(RequestUtil.getRemoteIP(RequestContext.getCurrentHttpRequest()));
		//----------------状态----------------
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_AWAITING_CONFIRMATION);
		salesOrder.setShipmentStatus(OrderConstants.SHIPMENT_STATUS_UNSHIP);
		salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_UNPAID);
		
		//----------------订单号----------------
		boolean isOrderNoAvailable = false;
		do{
			String orderNo = OrderCodeGenerator.generateOrderNo();
			Long size = salesOrderManager.getSizeByOrderNo(orderNo);
			if(size==0){
				//该编码可用
				isOrderNoAvailable = true;
				salesOrder.setOrderNo(orderNo);
			}
		}while(!isOrderNoAvailable);
		
		//----------------保存主体----------------
		salesOrderManager.save(salesOrder);
		
		//----------------订单促销----------------
		Shoppingcart shoppingcart = checkoutSession.getShoppingcart();
		if (shoppingcart.getIsUsedCoupon()!=null && shoppingcart.getIsUsedCoupon().equals(Shoppingcart.ISUSECOUPON_YES)) {
			//保存使用的优惠券
			salesOrder.setUsedCouponNo(shoppingcart.getUsedCouponNo());
			getPromoService().useCoupon(shoppingcart.getUsedCouponNo());
		}
		
		Set<ShoppingcartPromotion> shoppingcartPromotions = shoppingcart.getShoppingCartPromotions();
		if (shoppingcartPromotions != null) {
			for (ShoppingcartPromotion shoppingcartPromotion : shoppingcartPromotions) {
				OrderPromotion orderPromotion = new OrderPromotion(shoppingcartPromotion);
				orderPromotion.setSalesOrder(salesOrder);
				orderPromotionManager.save(orderPromotion);
			}
		}
		
		//促销赠送礼品
		List<Gift> giftList= shoppingcart.getPromoGiftList();
		for (Gift gift : giftList) {
			shoppingcart.addGiftItem(gift.getGiftCode(), gift.getOrderSkuQuantity());
		}
		//----------------订单明细项----------------
		Set<ShoppingcartItem> cartItems	= shoppingcart.getShoppingCartItems();
		for(ShoppingcartItem cartItem: cartItems){
			OrderSku orderSku = new OrderSku(cartItem);
			if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GC)){
				orderSku.getGiftCertificate().setOrderNo(salesOrder.getOrderNo());
				giftCertificateManager.createGiftCertificate4Order(orderSku.getGiftCertificate());
			}
			if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
				if(ContextUtil.getInstance().isFront()){
					//前台下单 分配库存时会检查库存
					Integer[] allcatedQty = inventoryManager.doAllocateStock(salesOrder, orderSku.getProductSku(), orderSku.getQuantity());
					orderSku.setAllocatedQuantity(allcatedQty[0]);
				}else{
					//后台下单 分配库存时不会检查库存
					Integer[] allcatedQty = inventoryManager.doAllocateStock4OrderAction(salesOrder, orderSku.getProductSku(), orderSku.getQuantity(), InventoryConstants.INVENTORY_AUDIT_EVENT_TYPE_STOCK_ALLOCATE);
					orderSku.setAllocatedQuantity(allcatedQty[0]);
				}
			}
			//礼品
			if (orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GIFT)) {
				Integer[] giftAllcatedQty = giftManager.doAllocateGift(salesOrder, orderSku.getGift(),orderSku.getQuantity());
				orderSku.setAllocatedQuantity(giftAllcatedQty[0]);
			}
			orderSku.setSalesOrder(salesOrder);
			orderSkuManager.save(orderSku);
		}
		//----------------订单日志----------------
		if(RequestContext.isFront()){
			orderAuditHelper.doLogCreateOrderByCustomer(salesOrder);
		}else{
			orderAuditHelper.doLogCreateOrderByAdmin(salesOrder);
		}
		
		//----------------start:支付----------------
		for (OrderPayment orderPayment: checkoutSession.generateOrderPayments()) {
			
			//礼券支付
			if (OrderConstants.PAYMENT_METHOD_GC.equals(orderPayment.getPaymentMethodId())) {
				giftCertificateManager.doUseGiftCertificate(orderPayment.getGiftCertificateNo(), orderPayment.getPaymentAmount(),salesOrder.getOrderNo());
			}
			
			//积分支付
			if (OrderConstants.PAYMENT_METHOD_POINT.equals(orderPayment.getPaymentMethodId())) {
				Customer customer = checkoutSession.getShoppingcart().getOwner();
				boolean succ = shopPointManager.updateShopPoint(customer, (- orderPayment.getUsedShopPoint()), ShopPoint.TYPE_PAY, salesOrder);
				if (!succ) {
					throw new ShopPointConsumptionException(customer.getShopPoint().getTotal(), orderPayment.getUsedShopPoint());
				}
			}
			//----------------收款单号----------------
			boolean isPaymentNoAvailable = false;
			do{
				String payNo = OrderCodeGenerator.generateOrderPaymentNo4Pay();
				Long size = orderPaymentManager.getSizeByDocumentNo(payNo);
				if(size==0){
					//该编码可用
					isPaymentNoAvailable = true;
					orderPayment.setDocumentNo(payNo);
				}
			}while(!isPaymentNoAvailable);
			orderPayment.setSalesOrder(salesOrder);
			orderPayment.setHasInvoice(salesOrder.getHasInvoice());
			orderPayment.setInvoiceTitle(salesOrder.getInvoiceTitle());
			orderPayment.setIpAddress(salesOrder.getIpAddress());
			orderPayment.setPayer(salesOrder.getCustomerFirstname());
			orderPayment.setPayTime(new Date());
			orderPaymentManager.save(orderPayment);
			
			
			//----------------首先设置为部分支付----------------
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_PARTIALLY_PAID);
			//----------------订单日志----------------
			orderAuditHelper.doLogPayOrder(salesOrder, orderPayment);
			
		}
		if(salesOrder.getUnPaidAmount().compareTo(BigDecimal.ZERO)==0){
			//如果应付金额为0
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_PAID);
		}
		//----------------end:支付----------------
		
		
		//----------------保存主体2----------------
		salesOrderManager.save(salesOrder);
		
		//----------------发通知邮件----------------
		//重新load一次
		salesOrderManager.flush();
		salesOrderManager.evict(salesOrder);
		SalesOrder orderAfter = salesOrderManager.getById(salesOrder.getSalesOrderId());
		salesOrderManager.sendEmail4PlaceOrder(orderAfter);
		
		return salesOrder;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doConfirmOrder(com.probiz.estore.common.model.order.SalesOrder)
	 */
	public void doConfirmOrder(SalesOrder salesOrder) throws OrderProccessFlowException{
		//----------------判断前提条件,尽量减少并发问题----------------
		if(!OrderConstants.ORDER_STATUS_AWAITING_CONFIRMATION.equals(salesOrder.getOrderStatus())){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		
		//----------------动作----------------
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_CONFIRMED);
		salesOrderManager.save(salesOrder);
		Map msgVariables = new HashMap();
		msgVariables.put("salesOrder", salesOrder);
		//---------------订单确认发送邮件、系统消息、手机短信--------------
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_CONFIRM, msgVariables, new String[]{salesOrder.getOrderAddress().getEmail()}, salesOrder.getCustomerId()!=null?new String[]{salesOrder.getCustomerId().toString()}:null, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
		//----------------订单日志----------------
		orderAuditHelper.doLogConfirmOrder(salesOrder);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doPayOrder(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.common.model.order.OrderPayment)
	 */
	public void doPayOrder(SalesOrder salesOrder,OrderPayment orderPayment) throws OrderProccessFlowException{
		//----------------判断前提条件,以避免并发问题----------------
		if(! (OrderConstants.ORDER_STATUS_CONFIRMED.equals(salesOrder.getOrderStatus()) || OrderConstants.ORDER_STATUS_HANDLING.equals(salesOrder.getOrderStatus()))){
			//状态判断
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		if( orderPayment.getPaymentAmount().compareTo(salesOrder.getUnPaidAmount()) > 0){
			//金额判断
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		//----------------动作----------------
		
		//----------------付款类型----------------
		String paymentTypeDesc = "";
		if(OrderConstants.PAYMENT_METHOD_OFFLINE.equals(orderPayment.getPaymentMethodId())){
			paymentTypeDesc += OrderConstants.PAYMENT_METHOD_OFFLINE_DESC;
		}else{
			PaymentMethod paymentMethod = paymentMethodManager.getById(orderPayment.getPaymentMethodId());
			paymentTypeDesc += paymentMethod.getPaymentMethodName();
		}
		if(null!= orderPayment.getPaymentType()){
			paymentTypeDesc += " " +OrderConstants.PAYMENT_TYPE_NAME_ARRAY[Integer.valueOf(orderPayment.getPaymentType())];
		}else if(StringUtils.isNotBlank(orderPayment.getPaymentGatewayName()))	{
			paymentTypeDesc += " " +orderPayment.getPaymentGatewayName();
		}
		orderPayment.setPaymentTypeDesc(paymentTypeDesc);
		//----------------收款单号----------------
		boolean isPaymentNoAvailable = false;
		do{
			String payNo = OrderCodeGenerator.generateOrderPaymentNo4Pay();
			Long size = orderPaymentManager.getSizeByDocumentNo(payNo);
			if(size==0){
				//该编码可用
				isPaymentNoAvailable = true;
				orderPayment.setDocumentNo(payNo);
			}
		}while(!isPaymentNoAvailable);
		//----------------收款单主体----------------
		orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_PAY);
		orderPayment.setSalesOrder(salesOrder);
		orderPayment.setHasInvoice(salesOrder.getHasInvoice());
		orderPayment.setInvoiceTitle(salesOrder.getInvoiceTitle());
		orderPayment.setIpAddress(RequestUtil.getRemoteIP(RequestContext.getCurrentHttpRequest()));
		orderPayment.setPayTime(new Date());
		orderPaymentManager.save(orderPayment);
		//----------------订单主体----------------
		salesOrder.setPaidAmount(salesOrder.getPaidAmount().add(orderPayment.getPaymentAmount()));
		if(NumberUtil.isZero(salesOrder.getUnPaidAmount())){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_PAID);
		}else if(NumberUtil.isZero(salesOrder.getPaidAmount())){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_UNPAID);
		}else{
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_PARTIALLY_PAID);
		}
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_HANDLING);
		salesOrderManager.save(salesOrder);
		Map map = new HashMap();
		map.put("orderPayment", orderPayment);
		//----------订单付款发送邮件、系统消息、手机短信-----
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_PAY, map, new String[]{salesOrder.getOrderAddress().getEmail()}, salesOrder.getCustomerId()!=null?new String[]{salesOrder.getCustomerId().toString()}:null, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
		//----------------订单日志----------------
		orderAuditHelper.doLogPayOrder(salesOrder,orderPayment);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doRefundOrder(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.common.model.order.OrderPayment)
	 */
	public void doRefundOrder(SalesOrder salesOrder,OrderPayment orderPayment) throws OrderProccessFlowException{
		//----------------判断前提条件,以避免并发问题----------------
		if(! (OrderConstants.ORDER_STATUS_CONFIRMED.equals(salesOrder.getOrderStatus()) || OrderConstants.ORDER_STATUS_HANDLING.equals(salesOrder.getOrderStatus()))){
			//状态判断
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		if( orderPayment.getPaymentAmount().compareTo(salesOrder.getPaidAmount()) > 0){
			//金额判断
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		//----------------动作----------------
		
		//----------------付款类型----------------
		String paymentTypeDesc = "";
		if(OrderConstants.PAYMENT_METHOD_OFFLINE.equals(orderPayment.getPaymentMethodId())){
			paymentTypeDesc += OrderConstants.PAYMENT_METHOD_OFFLINE_DESC;
		}else{
			PaymentMethod paymentMethod = paymentMethodManager.getById(orderPayment.getPaymentMethodId());
			paymentTypeDesc += paymentMethod.getPaymentMethodName();
		}
		if(null!= orderPayment.getPaymentType()){
			paymentTypeDesc += " " +OrderConstants.PAYMENT_TYPE_NAME_ARRAY[Integer.valueOf(orderPayment.getPaymentType())];
		}else if(StringUtils.isNotBlank(orderPayment.getPaymentGatewayName()))	{
			paymentTypeDesc += " " +orderPayment.getPaymentGatewayName();
		}	
		orderPayment.setPaymentTypeDesc(paymentTypeDesc);
		//----------------退款单号----------------
		boolean isPaymentNoAvailable = false;
		do{
			String payNo = OrderCodeGenerator.generateOrderPaymentNo4Refund();
			Long size = orderPaymentManager.getSizeByDocumentNo(payNo);
			if(size==0){
				//该编码可用
				isPaymentNoAvailable = true;
				orderPayment.setDocumentNo(payNo);
			}
		}while(!isPaymentNoAvailable);
		//----------------退款单主体----------------
		orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_REFUND);
		orderPayment.setSalesOrder(salesOrder);
		orderPayment.setHasInvoice(Constants.FLAG_FALSE);
		orderPayment.setIpAddress(RequestUtil.getRemoteIP(RequestContext.getCurrentHttpRequest()));
		orderPayment.setPayTime(new Date());
		orderPaymentManager.save(orderPayment);
		//----------------订单主体----------------
		salesOrder.setPaidAmount(salesOrder.getPaidAmount().add(orderPayment.getPaymentAmount().negate()));
		if(NumberUtil.isZero(salesOrder.getPaidAmount())){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_REFUND);
		}else{
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_PARTIALLY_REFUND);
		}
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_HANDLING);
		salesOrderManager.save(salesOrder);
		//----------订单退款发送邮件、系统消息、手机短信-----
		Map map = new HashMap();
		map.put("orderPayment", orderPayment);
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_RETURN_PAY, map, new String[]{salesOrder.getOrderAddress().getEmail()}, salesOrder.getCustomerId()!=null?new String[]{salesOrder.getCustomerId().toString()}:null, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
		
		//----------------订单日志----------------
		orderAuditHelper.doLogRefundOrder(salesOrder,orderPayment);
	}

	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doShipOrder(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.common.model.order.OrderShipment)
	 */
	public void doShipOrder(SalesOrder salesOrder,OrderShipment orderShipment) throws OrderProccessFlowException{
		//#重要 ：非事务查询必须在事务前
		//----------------动作----------------

		//----------------发货单号----------------
		boolean isShipNoAvailable = false;
		do{
			String shipNo = OrderCodeGenerator.generateOrderShipmentNo4Ship();
			Long size = orderShipmentManager.getSizeByDocumentNo(shipNo);
			if(size==0){
				//该编码可用
				isShipNoAvailable = true;
				orderShipment.setDocumentNo(shipNo);
			}
		}while(!isShipNoAvailable);
		
		//----------------发货地址----------------
		if(orderShipment.getShippingAddress().getRegionId() != null){
			Region region = regionManager.getById(orderShipment.getShippingAddress().getRegionId());
			orderShipment.getShippingAddress().setRegionFullName(region.getFullName());
		}
		orderAddressManager.save(orderShipment.getShippingAddress());
		
		//----------------发货单主体----------------
		orderShipment.setSalesOrder(salesOrder);
		orderShipment.setDocumentType(OrderShipment.DOCUMENT_TYPE_SHIP);
		orderShipment.setWrapId(salesOrder.getWrapId());
		orderShipment.setWrapName(salesOrder.getWrapName());
		orderShipment.setWrapNote(salesOrder.getWrapNote());
		if(orderShipment.getShippingRateId()!=null){
			ShippingRate shippingRate = shippingRateManager.getById(orderShipment.getShippingRateId());
			ShippingMethod shippingMethod = shippingRate.getShippingMethod();
			orderShipment.setShippingMethodId(shippingMethod.getShippingMethodId());
			if(salesOrder.isCod()){
				orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_COD+" "+shippingMethod.getShippingMethodName());
			}else{
				orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_CASH+" "+shippingMethod.getShippingMethodName());
			}
		}else if(orderShipment.getSelfCollectionCentreId()!=null){
			SelfCollectionCentre selfCollectionCentre = selfCollectionCentreManager.getById(orderShipment.getSelfCollectionCentreId());
			orderShipment.setSelfCollectionCentreName(selfCollectionCentre.getSelfCollectionCentreName());
			orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_SELFCOLLECT+" "+orderShipment.getShippingAddress().getRegionFullName()+","+selfCollectionCentre.getSelfCollectionCentreName());
		}else if(orderShipment.getOrderShipmentItems4Product().size() == 0){
			orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_GC);
		}else if(orderShipment.getIsVirtual()){
			orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_VIRTUAL);
		}
		orderShipment.setDeliveryTime(salesOrder.getDeliveryTime());
		orderShipment.setNeedConfrimB4Delivery(salesOrder.getNeedConfrimB4Delivery());
		orderShipment.setExceptedSelfCollectDate(salesOrder.getExceptedSelfCollectDate());
		orderShipmentManager.save(orderShipment);
		//----------------发货明细----------------
		for(OrderShipmentItem item: (Set<OrderShipmentItem>)orderShipment.getOrderShipmentItems()){
			item.setOrderShipment(orderShipment);
			OrderSku orderSku = orderSkuManager.getById(item.getOrderSkuId());
			//----------------start:判断前提条件,尽量减少并发问题----------------
			if(item.getDeliveryQuantity() > orderSku.getUnDeliveryQuantity()){
				throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
			}
			//----------------end:  判断前提条件,尽量减少并发问题----------------
			orderSku.setDeliveryQuantity(orderSku.getDeliveryQuantity()+item.getDeliveryQuantity());
			orderSku.setAllocatedQuantity(orderSku.getAllocatedQuantity()-item.getDeliveryQuantity());
			orderShipmentItemManager.save(item);
			orderSkuManager.save(orderSku);
			//----------释放库存---------------
			if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
				inventoryManager.doReleaseStock(salesOrder, orderSku.getProductSku(), item.getDeliveryQuantity());
			} else if (orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GIFT)){ 
				giftManager.doReleaseGift(salesOrder, orderSku.getGift(),item.getDeliveryQuantity());
			}else{
				giftCertificateService.doSendGiftCertificate(orderSku.getGiftCertificate(), salesOrder.getOrderNo());
			}
		}
		//----------------订单主体----------------
		boolean shipAllflag = true; //是全部发货
		for(OrderSku orderSku: (Set<OrderSku>)salesOrder.getOrderSkus()){
			if(orderSku.getUnDeliveryQuantity() > 0){
				shipAllflag = false;
			}
		}
		if(shipAllflag){
			salesOrder.setShipmentStatus(OrderConstants.SHIPMENT_STATUS_ALL_SHIPPED);
		}else{
			salesOrder.setShipmentStatus(OrderConstants.SHIPMENT_STATUS_PARTIALLY_SHIPPED);
		}
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_HANDLING);
		salesOrderManager.save(salesOrder);
		
		//----------------订单日志----------------
		orderAuditHelper.doLogShipOrder(salesOrder,orderShipment);
		
		//----------------发通知邮件----------------
		if(orderShipment.getOrderShipmentItems4Product().size() > 0){
			//礼券发送则不需发通知
			salesOrderManager.sendEmail4Ship(salesOrder,orderShipment);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doReturnOrder(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.common.model.order.OrderShipment)
	 */
	public void doReturnOrder(SalesOrder salesOrder,OrderShipment orderShipment) throws OrderProccessFlowException{
		//----------------判断前提条件,尽量减少并发问题----------------
		
		//----------------动作----------------
		//----------------退货单号----------------
		boolean isReturnNoAvailable = false;
		do{
			String shipNo = OrderCodeGenerator.generateOrderShipmentNo4Return();
			Long size = orderShipmentManager.getSizeByDocumentNo(shipNo);
			if(size==0){
				//该编码可用
				isReturnNoAvailable = true;
				orderShipment.setDocumentNo(shipNo);
			}
		}while(!isReturnNoAvailable);
		//----------------发货地址----------------
		Region region = regionManager.getById(orderShipment.getShippingAddress().getRegionId());
		orderShipment.getShippingAddress().setRegionFullName(region.getFullName());
		orderAddressManager.save(orderShipment.getShippingAddress());
		
		//----------------退货单主体----------------
		orderShipment.setSalesOrder(salesOrder);
		orderShipment.setDocumentType(OrderShipment.DOCUMENT_TYPE_RETURN);
		if(orderShipment.getShippingRateId()!=null){
			ShippingRate shippingRate = shippingRateManager.getById(orderShipment.getShippingRateId());
			ShippingMethod shippingMethod = shippingRate.getShippingMethod();
			orderShipment.setShippingMethodId(shippingMethod.getShippingMethodId());
			if(salesOrder.isCod()){
				orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_COD+" "+shippingMethod.getShippingMethodName());
			}else{
				orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_CASH+" "+shippingMethod.getShippingMethodName());
			}
		}else if(orderShipment.getSelfCollectionCentreId()!=null){
			SelfCollectionCentre selfCollectionCentre = selfCollectionCentreManager.getById(orderShipment.getSelfCollectionCentreId());
			orderShipment.setSelfCollectionCentreName(selfCollectionCentre.getSelfCollectionCentreName());
			orderShipment.setDeliveryTypeDesc(OrderConstants.DELIVERY_TYPE_SELFCOLLECT+" "+orderShipment.getShippingAddress().getRegionFullName()+","+selfCollectionCentre.getSelfCollectionCentreName());
		}
		orderShipment.setNeedConfrimB4Delivery(salesOrder.getNeedConfrimB4Delivery());
		orderShipment.setDeliveryTime(salesOrder.getDeliveryTime());
		orderShipmentManager.save(orderShipment);
		//----------------发货明细----------------
		for(OrderShipmentItem item: (Set<OrderShipmentItem>)orderShipment.getOrderShipmentItems()){
			item.setOrderShipment(orderShipment);
			OrderSku orderSku = orderSkuManager.getById(item.getOrderSkuId());
			//----------------start:判断前提条件,尽量减少并发问题----------------
			if(item.getDeliveryQuantity() > orderSku.getDeliveryQuantity()){
				throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
			}
			//----------------end:  判断前提条件,尽量减少并发问题----------------
			orderSku.setDeliveryQuantity(orderSku.getDeliveryQuantity()-item.getDeliveryQuantity());
			orderSku.setAllocatedQuantity(orderSku.getAllocatedQuantity()+item.getDeliveryQuantity());
			orderShipmentItemManager.save(item);
			orderSkuManager.save(orderSku);
			//----------释放库存---------------
			if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
				//先入库
				inventoryManager.doAddStock4OrderReturn(salesOrder,orderSku.getProductSku(), item.getIncomingQuantity());
				//注意：退货后分配库存
				inventoryManager.doAllocateStock4OrderAction(salesOrder,orderSku.getProductSku(), item.getDeliveryQuantity());
			}
		}
		//----------------订单主体----------------
		boolean returnAllflag = true; //是全部发货
		for(OrderSku orderSku: (Set<OrderSku>)salesOrder.getOrderSkus()){
			if(orderSku.getDeliveryQuantity() > 0){
				returnAllflag = false;
			}
		}
		if(returnAllflag){
			salesOrder.setShipmentStatus(OrderConstants.SHIPMENT_STATUS_ALL_RETURNED);
		}else{
			salesOrder.setShipmentStatus(OrderConstants.SHIPMENT_STATUS_PARTIALLY_RETURNED);
		}
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_HANDLING);
		salesOrderManager.save(salesOrder);
		//----------订单退货发送邮件、系统消息、手机短信-----
		Map map = new HashMap();
		map.put("orderShipment", orderShipment);
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_EEJECTED_GOODS, map, new String[]{salesOrder.getOrderAddress().getEmail()}, salesOrder.getCustomerId()!=null?new String[]{salesOrder.getCustomerId().toString()}:null, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
		
		//----------------订单日志----------------
		orderAuditHelper.doLogReturnOrder(salesOrder,orderShipment);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doCompleteOrder(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.order.model.OrderCompleteModel)
	 */
	public void doCompleteOrder(SalesOrder salesOrder,OrderCompleteModel completeModel) throws OrderProccessFlowException{
		//----------------判断前提条件,尽量减少并发问题----------------
		if(! (OrderConstants.ORDER_STATUS_HANDLING.equals(salesOrder.getOrderStatus()) || OrderConstants.ORDER_STATUS_CONFIRMED.equals(salesOrder.getOrderStatus()))){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		
		//----------------动作----------------
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_COMPLETE);
		salesOrderManager.save(salesOrder);
		//----------释放库存---------------
		for(OrderSku orderSku: (Set<OrderSku>)salesOrder.getOrderSkus()){
			if(orderSku.getUnDeliveryQuantity() > 0){
				//----------取消未发送的货品库存---------------
				if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
					inventoryManager.doCancelAllocateStock(salesOrder, orderSku.getProductSku(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}else if (orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GIFT)){ 
					// 礼品
					giftManager.doCanCelAllocateGift(salesOrder, orderSku.getGift(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}
			}
		}
		//----------赠送优惠券---------------
		if(completeModel.isSendCoupon() && salesOrder.getGainedCouponTypeId()!=null){
			doSendCoupon(salesOrder);
			completeModel.setCouponSendCommit(true);
		}
		//----------赠送积分---------------
		
		if(completeModel.isSendShopPoint() && salesOrder.getCustomerId()!=null  && completeModel.getShopPoint() > 0 && completeModel.getShopPoint()<=salesOrder.getGainedPoint()){
			doSendShopPoint(salesOrder,completeModel.getShopPoint());
			completeModel.setShopPointSendCommit(true);
			salesOrder.setGainedPointAtLast(completeModel.getShopPoint());
		}else{
			salesOrder.setGainedPointAtLast(0);
		}
		salesOrderManager.save(salesOrder);
		
		List<Integer> productIdList = new ArrayList<Integer>();
		for(OrderSku orderSku:(List<OrderSku>)salesOrder.getOrderSkus4Product()){
			if(orderSku.getDeliveryQuantity() > 0){
				//只有发货数量大于0 才生效。 增加商品的购买次数和数量和评论资格，用于统计
				if(!productIdList.contains(orderSku.getProductId())){
					//如果前面已增加购买次数，那么这里不需要添加
					productService.doIncreaseOneBuyTimes(orderSku.getProductId());
				}
				productService.doUpdateStatBuyCount(orderSku.getProductId(),orderSku.getDeliveryQuantity());
				
				//增加评论资格
				customerService.addEligibility(salesOrder.getCustomerId(), orderSku.getProductId());
				productIdList.add(orderSku.getProductId());
			}
		}
		//----------处理礼券支付交易状态：此段已无用---------------
		for (OrderPayment orderPayment: (Set<OrderPayment>)salesOrder.getOrderPayments()) {
			//礼券支付
			if (OrderConstants.PAYMENT_METHOD_GC.equals(orderPayment.getPaymentMethodId())) {
				try {
					giftCertificateManager.doCompleteUseGiftCertificate(orderPayment.getGiftCertificateNo(), orderPayment.getPaymentAmount(),salesOrder.getOrderNo());
				} catch (GiftCertificateStateException e) {
					e.printStackTrace();
				}
			}
			
		}
		
		//增加alsoBuy
		recommendedService.saveAlsoBuy(productIdList);
		
		//----------------订单日志----------------
		orderAuditHelper.doLogCompleteOrder(salesOrder,completeModel);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doCancelOrderByAdmin(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.order.model.OrderCancelModel)
	 */
	public void doCancelOrderByAdmin(SalesOrder salesOrder, OrderCancelModel cancelModel) throws OrderProccessFlowException{
		//----------------判断前提条件,尽量减少并发问题----------------
		if(OrderConstants.ORDER_STATUS_COMPLETE.equals(salesOrder.getOrderStatus())){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		
		//----------------动作----------------
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_CANCELLED_ADMIN);
		salesOrderManager.save(salesOrder);
		//----------释放库存---------------
		for(OrderSku orderSku: (Set<OrderSku>)salesOrder.getOrderSkus()){
			if(orderSku.getUnDeliveryQuantity() > 0){
				//----------释放库存---------------
				if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
					inventoryManager.doCancelAllocateStock(salesOrder, orderSku.getProductSku(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}else if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GIFT)){
					giftManager.doCanCelAllocateGift(salesOrder, orderSku.getGift(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}
			}
		}
		
		//----------退还使用的优惠券---------------
		if(cancelModel.isReturnUsedCouponNo() && StringUtils.isNotBlank(salesOrder.getUsedCouponNo())){
			getPromoService().returnCoupon(salesOrder.getUsedCouponNo());
			cancelModel.setUsedCouponNoReturnCommit(true);
		}
		
		//----------=========== start:退还支付的积分  ===========---------------
		BigDecimal returnPointMoney = BigDecimal.ZERO;
		if(cancelModel.isReturnShopPoint() && salesOrder.getCustomerId()!=null && cancelModel.getShopPoint() > 0 && cancelModel.getShopPoint() <= salesOrder.getUsedShopPoint()){
			doReturnShopPoint(salesOrder,cancelModel.getShopPoint());
			cancelModel.setShopPointReturnCommit(true);
			
			double rate = (double)cancelModel.getShopPoint()/(double)salesOrder.getUsedShopPoint();
			returnPointMoney = salesOrder.getPointPaid().multiply(new BigDecimal(rate));
			returnPointMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
			salesOrder.setPointPaid(salesOrder.getPointPaid().add(returnPointMoney.negate()));

			//积分退款单
			refundPoint4CancelOrder(salesOrder, cancelModel.getShopPoint(),returnPointMoney);
		}
		
		//----------=========== end:退还支付的积分 ===========---------------
		
		
		//----------=========== start:退还支付的礼券金额 ===========---------------
		doReturnGiftCertificateMoney4Admin(salesOrder,cancelModel);
		//礼券退款单
		refundGc4CancelOrder(salesOrder, cancelModel);
		//----------=========== end:退还支付的礼券金额 ===========---------------
		
		
		//----------计算退还的礼券总金额---------------
		BigDecimal returnGcMoney = BigDecimal.ZERO;
		for(BigDecimal gcMoney : cancelModel.getGiftCertificateMoneyList()){
			returnGcMoney = returnGcMoney.add(gcMoney);
		}
		salesOrder.setGiftCertificatePaid(salesOrder.getGiftCertificatePaid().add(returnGcMoney.negate()));
		salesOrder.setPaidAmount(salesOrder.getPaidAmount().add(returnPointMoney.negate()).add(returnGcMoney.negate()));
		if(returnPointMoney.compareTo(BigDecimal.ZERO)>0 || returnGcMoney.compareTo(BigDecimal.ZERO)>0){
			if(salesOrder.getPaidAmount().compareTo(BigDecimal.ZERO) > 0){
				salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_PARTIALLY_REFUND);
			}else{
				salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_REFUND);
			}
		}
		
		
		salesOrderManager.save(salesOrder);
		
		
		
		//----------订单作废发送邮件、系统消息、手机短信-----
		Map map = new HashMap();
		map.put("salesOrder", salesOrder);
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_CANCEL, map, new String[]{salesOrder.getOrderAddress().getEmail()}, salesOrder.getCustomerId()!=null?new String[]{salesOrder.getCustomerId().toString()}:null, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
		
		//----------------订单日志----------------
		orderAuditHelper.doLogCancelOrderByAdmin(salesOrder,cancelModel);
	}
	/**
	 * 取消订单   礼券退款
	 * @param salesOrder
	 * @param returnPointMoney
	 */
	private void refundGc4CancelOrder(SalesOrder salesOrder, OrderCancelModel cancelModel) {
		if(cancelModel.getGiftCertificateNoList().size() > 0){
			for(int i=0; i< cancelModel.getGiftCertificateNoList().size(); i++){
				BigDecimal returnGcMoney = cancelModel.getGiftCertificateMoneyList().get(i);
				String giftCertificateNo = cancelModel.getGiftCertificateNoList().get(i);
				//礼券退款单
				//----------------礼券退款单号----------------
				OrderPayment orderPayment = new OrderPayment();
				boolean isPaymentNoAvailable = false;
				do{
					String payNo = OrderCodeGenerator.generateOrderPaymentNo4Refund();
					Long size = orderPaymentManager.getSizeByDocumentNo(payNo);
					if(size==0){
						//该编码可用
						isPaymentNoAvailable = true;
						orderPayment.setDocumentNo(payNo);
					}
				}while(!isPaymentNoAvailable);
				//----------------积分退款单主体----------------
				orderPayment.setPaymentAmount(returnGcMoney);
				orderPayment.setGiftCertificateNo(giftCertificateNo);
				orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_REFUND);
				orderPayment.setPaymentMethodId(OrderConstants.REFUND_METHOD_GC);
				orderPayment.setPaymentTypeDesc(OrderConstants.REFUND_METHOD_GC_DESC);
				orderPayment.setSalesOrder(salesOrder);
				orderPayment.setPayee(salesOrder.getCustomerFullName());
				orderPayment.setReturnReason(OrderConstants.REFUND_REASON_CANCEL_ORDER);
				orderPayment.setHasInvoice(Constants.FLAG_FALSE);
				orderPayment.setIpAddress(RequestUtil.getRemoteIP(RequestContext.getCurrentHttpRequest()));
				orderPayment.setPayTime(new Date());
				orderPaymentManager.save(orderPayment);
			}
		}
	}
	/**
	 * 取消订单   积分退款
	 * @param salesOrder
	 * @param point
	 * @param returnPointMoney
	 */
	private void refundPoint4CancelOrder(SalesOrder salesOrder,Integer point, BigDecimal returnPointMoney) {
		//----------------积分退款单号----------------
		OrderPayment orderPayment = new OrderPayment();
		boolean isPaymentNoAvailable = false;
		do{
			String payNo = OrderCodeGenerator.generateOrderPaymentNo4Refund();
			Long size = orderPaymentManager.getSizeByDocumentNo(payNo);
			if(size==0){
				//该编码可用
				isPaymentNoAvailable = true;
				orderPayment.setDocumentNo(payNo);
			}
		}while(!isPaymentNoAvailable);
		//----------------积分退款单主体----------------
		orderPayment.setPaymentAmount(returnPointMoney);
		orderPayment.setUsedShopPoint(point);
		orderPayment.setDocumentType(OrderPayment.DOCUMENT_TYPE_REFUND);
		orderPayment.setPaymentMethodId(OrderConstants.REFUND_METHOD_POINT);
		orderPayment.setPaymentTypeDesc(OrderConstants.REFUND_METHOD_POINT_DESC);
		orderPayment.setSalesOrder(salesOrder);
		orderPayment.setPayee(salesOrder.getCustomerFullName());
		orderPayment.setReturnReason(OrderConstants.REFUND_REASON_CANCEL_ORDER);
		orderPayment.setHasInvoice(Constants.FLAG_FALSE);
		orderPayment.setIpAddress(RequestUtil.getRemoteIP(RequestContext.getCurrentHttpRequest()));
		orderPayment.setPayTime(new Date());
		orderPaymentManager.save(orderPayment);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doCancelOrderByCustomer(com.probiz.estore.common.model.order.SalesOrder)
	 */
	public void doCancelOrderByCustomer(SalesOrder salesOrder) throws OrderProccessFlowException{
		//----------------判断前提条件,尽量减少并发问题----------------
		if(OrderConstants.ORDER_STATUS_COMPLETE.equals(salesOrder.getOrderStatus())){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		if(!salesOrder.isCancelByCustomerEnabled()){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		
		//----------------动作----------------
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_CANCELLED_CUSTOMER);
		salesOrderManager.save(salesOrder);
		//----------释放库存---------------
		for(OrderSku orderSku: (Set<OrderSku>)salesOrder.getOrderSkus()){
			if(orderSku.getUnDeliveryQuantity() > 0){
				//----------释放库存---------------
				if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
					inventoryManager.doCancelAllocateStock(salesOrder, orderSku.getProductSku(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}else if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GIFT)){
					giftManager.doCanCelAllocateGift(salesOrder, orderSku.getGift(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}
			}
		}
		OrderCancelModel cancelModel = new OrderCancelModel();
		//----------退还使用的优惠券---------------
		if(StringUtils.isNotBlank(salesOrder.getUsedCouponNo())){
			getPromoService().returnCoupon(salesOrder.getUsedCouponNo());
			cancelModel.setUsedCouponNoReturnCommit(true);
		}
		//----------退还支付的积分---------------
		if(salesOrder.getCustomerId()!=null && salesOrder.getUsedShopPoint()!=null 	&& salesOrder.getUsedShopPoint().intValue()>0){
			doReturnShopPoint(salesOrder);
			cancelModel.setShopPoint(salesOrder.getUsedShopPoint());
			cancelModel.setShopPointReturnCommit(true);
			
			//积分退款单
			refundPoint4CancelOrder(salesOrder,salesOrder.getUsedShopPoint(), salesOrder.getPointPaid());
		}
		//----------退还支付的礼券金额---------------
		doReturnGiftCertificateMoney(salesOrder,cancelModel);
		//礼券退款单
		refundGc4CancelOrder(salesOrder, cancelModel);
		
		
		//----------设置退款状态---------------
		if(salesOrder.getPaidAmount().compareTo(BigDecimal.ZERO) > 0){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_REFUND);
		}
		salesOrder.setPointPaid(BigDecimal.ZERO);
		salesOrder.setGiftCertificatePaid(BigDecimal.ZERO);
		salesOrder.setPaidAmount(BigDecimal.ZERO);
		salesOrderManager.save(salesOrder);
		//----------订单作废发送邮件、系统消息、手机短信-----
		Map map = new HashMap();
		map.put("salesOrder", salesOrder);
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_ORDER_CANCEL, map, new String[]{salesOrder.getOrderAddress().getEmail()}, salesOrder.getCustomerId()!=null?new String[]{salesOrder.getCustomerId().toString()}:null, new String[]{salesOrder.getOrderAddress().getPhoneNumber()});
		
		//----------------订单日志----------------
		orderAuditHelper.doLogCancelOrderByCustomer(salesOrder,cancelModel);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doCancelOrder4NotPaid(com.probiz.estore.common.model.order.SalesOrder)
	 */
	public void doCancelOrder4NotPaid(SalesOrder salesOrder) throws OrderProccessFlowException{
		//----------------判断前提条件,尽量减少并发问题----------------
		if(OrderConstants.ORDER_STATUS_COMPLETE.equals(salesOrder.getOrderStatus())){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		
		//----------------动作----------------
		salesOrder.setOrderStatus(OrderConstants.ORDER_STATUS_CANCELLED_PAY_TIMEOUT);
		salesOrderManager.save(salesOrder);
		//----------释放库存---------------
		for(OrderSku orderSku: (Set<OrderSku>)salesOrder.getOrderSkus()){
			if(orderSku.getUnDeliveryQuantity() > 0){
				//----------释放库存---------------
				if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_PRODUCT)){
					inventoryManager.doCancelAllocateStock(salesOrder, orderSku.getProductSku(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}else if(orderSku.getItemType().equals(OrderSku.ITEM_TYPE_GIFT)){
					giftManager.doCanCelAllocateGift(salesOrder, orderSku.getGift(), orderSku.getUnDeliveryQuantity());
					orderSku.setAllocatedQuantity(0);
					orderSkuManager.save(orderSku);
				}
			}
		}
		
		OrderCancelModel cancelModel = new OrderCancelModel();
		//----------退还使用的优惠券---------------
		if(StringUtils.isNotBlank(salesOrder.getUsedCouponNo())){
			getPromoService().returnCoupon(salesOrder.getUsedCouponNo());
			cancelModel.setUsedCouponNoReturnCommit(true);
		}
		//----------退还支付的积分---------------
		if(salesOrder.getCustomerId()!=null && salesOrder.getUsedShopPoint()!=null 	&& salesOrder.getUsedShopPoint().intValue()>0){
			doReturnShopPoint(salesOrder);
			cancelModel.setShopPoint(salesOrder.getUsedShopPoint());
			cancelModel.setShopPointReturnCommit(true);
			
			//积分退款单
			refundPoint4CancelOrder(salesOrder,salesOrder.getUsedShopPoint(), salesOrder.getPointPaid());
		}
		//----------退还支付的礼券金额---------------
		doReturnGiftCertificateMoney(salesOrder,cancelModel);
		//礼券退款单
		refundGc4CancelOrder(salesOrder, cancelModel);
		
		//----------设置退款状态---------------
		if(salesOrder.getPaidAmount().compareTo(BigDecimal.ZERO) > 0){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_REFUND);
		}
		salesOrder.setPointPaid(BigDecimal.ZERO);
		salesOrder.setGiftCertificatePaid(BigDecimal.ZERO);
		salesOrder.setPaidAmount(BigDecimal.ZERO);
		salesOrderManager.save(salesOrder);
		
		//----------------订单日志----------------
		orderAuditHelper.doLogCancelOrder4NotPaid(salesOrder,cancelModel);
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doPickOrder(java.util.Set)
	 * 将订单尚未发货的商品集结成单
	 */
	public OrderPick doPickOrder(Set<String> orderNos) throws OrderProccessFlowException{
		//----------------动作----------------
		OrderPick orderPick = new OrderPick();
		//----------------备货单号----------------
		boolean isPickNoAvailable = false;
		do{
			String shipNo = OrderCodeGenerator.generateOrderPickNo();
			Long size = orderPickManager.getSizeByDocumentNo(shipNo);
			if(size==0){
				//该编码可用
				isPickNoAvailable = true;
				orderPick.setDocumentNo(shipNo);
			}
		}while(!isPickNoAvailable);
		
		//----------------设置备货单明细----------------
		for(String orderNo: orderNos){
			SalesOrder salesOrder = salesOrderManager.getSalesOrderByOrderNo(orderNo);
			if(OrderConstants.ORDER_STATUS_CONFIRMED.equals(salesOrder.getOrderStatus()) || OrderConstants.ORDER_STATUS_HANDLING.equals(salesOrder.getOrderStatus())){
				//订单状态为：等待确认、已完成和作废的订单不会加入备货单
				for(OrderSku orderSku : salesOrder.getOrderSkus4Product()){
					OrderPickItem currOrderPickItem = null;
					for(OrderPickItem orderPickItem: (Set<OrderPickItem>)orderPick.getOrderPickItems()){
						if(orderPickItem.getProductSkuId().equals(orderSku.getProductSkuId())){
							currOrderPickItem = orderPickItem;
							break;
						}
					}
					if(currOrderPickItem == null){
						if(orderSku.getUnDeliveryQuantity() > 0){
							currOrderPickItem = new OrderPickItem();
							currOrderPickItem.setOrderPick(orderPick);
							currOrderPickItem.setItemType(orderSku.getItemType());
							currOrderPickItem.setProductSkuId(orderSku.getProductSkuId());
							currOrderPickItem.setProductId(orderSku.getProductId());
							currOrderPickItem.setProductName(orderSku.getProductName());
							currOrderPickItem.setProductSkuCode(orderSku.getProductSkuCode());
							currOrderPickItem.setDisplaySkuOptions(orderSku.getDisplaySkuOptions());
							currOrderPickItem.setPickQuantity(orderSku.getUnDeliveryQuantity());
							orderPick.getOrderPickItems().add(currOrderPickItem);
						}
					}else{
						currOrderPickItem.setPickQuantity(currOrderPickItem.getPickQuantity()+orderSku.getUnDeliveryQuantity());
					}
				}
				
				//礼品生成备货单
				for(OrderSku orderSku : salesOrder.getOrderSkus4Gift()){
					OrderPickItem currOrderPickItem = null;
					for(OrderPickItem orderPickItem: (Set<OrderPickItem>)orderPick.getOrderPickItems()){
						if(orderPickItem.getProductSkuId().equals(orderSku.getGift().getGiftId()) && Constants.ITEM_TYPE_GIFT.equals(orderPickItem.getItemType())){
							currOrderPickItem = orderPickItem;
							break;
						}
					}
					if(currOrderPickItem == null){
						if(orderSku.getUnDeliveryQuantity() > 0){
							currOrderPickItem = new OrderPickItem();
							currOrderPickItem.setOrderPick(orderPick);
							currOrderPickItem.setItemType(orderSku.getItemType());
							currOrderPickItem.setProductSkuId(orderSku.getGift().getGiftId());
							currOrderPickItem.setProductId(orderSku.getGift().getGiftId());
							currOrderPickItem.setProductName(orderSku.getProductName());
							currOrderPickItem.setProductSkuCode(orderSku.getProductSkuCode());
							currOrderPickItem.setDisplaySkuOptions(orderSku.getDisplaySkuOptions());
							currOrderPickItem.setPickQuantity(orderSku.getUnDeliveryQuantity());
							orderPick.getOrderPickItems().add(currOrderPickItem);
						}
					}else{
						currOrderPickItem.setPickQuantity(currOrderPickItem.getPickQuantity()+orderSku.getUnDeliveryQuantity());
					}
				}
				//----------------订单日志----------------
				orderAuditHelper.doLogPickOrder(salesOrder, orderPick);
				//----------------用于显示----------------
				orderPick.getSuccessOrderList().add(salesOrder.getOrderNo());
				
			}else{
				orderPick.getFailOrderList().add(salesOrder.getOrderNo());
			}
		}
		if(orderPick.getSuccessOrderList().size()>0 && orderPick.getOrderPickItems().size() > 0){
			//必须有成功的订单和备货项才保存
			//----------------最后才保存主体----------------
			orderPickManager.save(orderPick);
			//----------------保存备货单明细----------------
			for(OrderPickItem orderPickItem: (Set<OrderPickItem>)orderPick.getOrderPickItems()){
				orderPickItemManager.save(orderPickItem);
			}
		}
		return orderPick;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#buildCheckoutSession4Admin(javax.servlet.http.HttpServletRequest)
	 */
	public CheckoutSession buildCheckoutSession4Admin(HttpServletRequest request){
		CheckoutSession checkoutSession = new CheckoutSession(true);
		
		
		//--------------start： 处理购物车信息---------------
		Shoppingcart shoppingcart = new Shoppingcart();
		checkoutSession.setShoppingcart(shoppingcart);
		try {
			String[] productSkuCodes = RequestUtil.getParameterValuesNullSafe(request, "productSkuCodes");
			String[] skuQuantities = RequestUtil.getParameterValuesNullSafe(request, "skuQuantities");
			for(int i=0; i< productSkuCodes.length ; i++){
				//注意：不检查库存	
				productService.checkMinPurchaseQuantity(productSkuCodes[i], Integer.valueOf(skuQuantities[i]));
				shoppingcart.addProductItem(productSkuCodes[i], Integer.valueOf(skuQuantities[i]));

			}
			
			//---------------------注意1：礼券购买，这里只是虚拟用于订单编辑，并没有真正购买---------
			String[] giftCertAmts = RequestUtil.getParameterValuesNullSafe(request, "giftCertAmts");
			for(int i=0; i< giftCertAmts.length ; i++){
				ShoppingcartItemGc shoppingcartItemGc = new ShoppingcartItemGc();
				shoppingcartItemGc.setGiftCertAmt(new BigDecimal(giftCertAmts[i]));
				shoppingcart.addGiftCertificateItem(shoppingcartItemGc);
			}
			//---------------------注意2：使用了的优惠券，这里只是虚拟用于订单编辑，记录订单使用的优惠券号，为了之后的订单计算中与前台下单数据保存一致---------
			String usedCouponNo = RequestUtil.getParameterNullSafe(request, "usedCouponNo");
			if(StringUtils.isNotBlank(usedCouponNo)){
				shoppingcart.setUsedCouponNo(usedCouponNo);
			}
			
			
		} catch (UnderMinimumPurchaseQuantityException e) {
			checkoutSession.setErrorMsg(e.getMessage());	
		}
		//--------------end：   处理购物车信息---------------
		
		//--------------start： 处理订单信息---------------
		JSONObject jsonObject = new JSONObject();
		Map params = request.getParameterMap();
		for(String key: (Set<String>)params.keySet()){
			jsonObject.put(key, request.getParameter(key));
		}
		
		checkoutSession.setDataToEmptyStringForNull(jsonObject);
		checkoutSession.setCustomerId(jsonObject);
		checkoutSession.setConsigneeData(jsonObject);
		checkoutSession.setPaymentMethodData(jsonObject);
		checkoutSession.setRemarkData(jsonObject);
		checkoutSession.setInvoiceData(jsonObject);
		checkoutSession.setGiftWrapData(jsonObject);
		//--------------end：   处理订单信息---------------
		return checkoutSession;
		
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.order.service.OrderProcessFlowManager#doEditOrder(com.probiz.estore.common.model.order.SalesOrder, com.probiz.estore.common.model.order.CheckoutSession)
	 */
	public void doEditOrder(SalesOrder salesOrder,CheckoutSession checkoutSession) throws OrderProccessFlowException{

		//----------------判断前提条件,尽量减少并发问题----------------
		if(! (OrderConstants.ORDER_STATUS_AWAITING_CONFIRMATION.equals(salesOrder.getOrderStatus()) || OrderConstants.ORDER_STATUS_CONFIRMED.equals(salesOrder.getOrderStatus()))){
			throw new OrderProccessFlowException(getMessage("orderProccessFlow.message.action.false"));
		}
		//----------------动作----------------
		//----------------处理订单金额和主体----------------
		SalesOrder mockSalesOrder = checkoutSession.generateSalesOrder();
		salesOrder.setProductCost(mockSalesOrder.getProductCost());
		salesOrder.setTotalAmount(salesOrder.calcTotal()); //注意，因为价格已映射
		salesOrder.setWrapId(mockSalesOrder.getWrapId());
		salesOrder.setWrapName(mockSalesOrder.getWrapName());
		salesOrder.setWrapNote(mockSalesOrder.getWrapNote());
		salesOrder.setHasInvoice(mockSalesOrder.getHasInvoice());
		salesOrder.setInvoiceTitle(mockSalesOrder.getInvoiceTitle());
		salesOrder.setRemark(mockSalesOrder.getRemark());
		salesOrder.setPaymentMethodId(mockSalesOrder.getPaymentMethodId());
		salesOrder.setPaymentType(mockSalesOrder.getPaymentType());
		salesOrder.setPaymentTypeDesc(mockSalesOrder.getPaymentTypeDesc());
		salesOrder.setShippingMethodId(mockSalesOrder.getShippingMethodId());
		salesOrder.setDeliveryTypeDesc(mockSalesOrder.getDeliveryTypeDesc());
		salesOrder.setNeedConfrimB4Delivery(mockSalesOrder.getNeedConfrimB4Delivery());
		salesOrder.setDeliveryTime(mockSalesOrder.getDeliveryTime());
		salesOrder.setSelfCollectionCentreId(mockSalesOrder.getSelfCollectionCentreId());
		salesOrder.setSelfCollectionCentreName(mockSalesOrder.getSelfCollectionCentreName());
		salesOrder.setExceptedSelfCollectDate(mockSalesOrder.getExceptedSelfCollectDate());
		//--------------订单支付状态--------------
		if(NumberUtil.isZero(salesOrder.getUnPaidAmount())){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_ALL_PAID);
		}else if(NumberUtil.isZero(salesOrder.getPaidAmount())){
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_UNPAID);
		}else{
			salesOrder.setPaymentStatus(OrderConstants.PAYMENT_STATUS_PARTIALLY_PAID);
		}
		
		salesOrderManager.save(salesOrder);
		//----------------处理订单地址----------------
		OrderAddress orderAddress = salesOrder.getOrderAddress();
		orderAddress.applyAddress(checkoutSession.generateAddress());
		orderAddressManager.save(orderAddress);
		
		//----------------start:处理礼品，释放库存----------------
		//释放库存。先将数量返回到库存中
		for (OrderSku orderSku: salesOrder.getOrderSkus4Gift()){
			if (orderSku.getIs_Gift()) {
				Gift gift = giftManager.getById(orderSku.getGift().getGiftId());
				giftManager.doCanCelAllocateGift(salesOrder, orderSku.getGift(), orderSku.getQuantity());
			}
		}
		
		//促销赠送礼品（必须在以上的释放库存代码之后）
		List<Gift> giftList= checkoutSession.getShoppingcart().getPromoGiftList();
		for (Gift gift : giftList) {
			checkoutSession.getShoppingcart().addGiftItem(gift.getGiftCode(), gift.getOrderSkuQuantity());
		}
		
		// 当促销中没有礼品时，还原上面释放礼品的库存。即返回未处理前的数量
		if(giftList.size() <1 && salesOrder.getOrderSkus4Gift().size() >0) {
			for (OrderSku orderSku: salesOrder.getOrderSkus4Gift()){
				if (orderSku.getIs_Gift()) {
					Gift gift = giftManager.getById(orderSku.getGift().getGiftId());
					giftManager.doCanCelAllocateGift(salesOrder, orderSku.getGift(), -orderSku.getQuantity());
				}
			}
		}

		//----------------start:促销赠送礼品并得到最新的促销规则----------------
		List<PromoRule> promoRules = new ArrayList<PromoRule>();
		Set<ShoppingcartPromotion> shoppingcartPromotions = checkoutSession.getShoppingcart().getShoppingCartPromotions();
		for (ShoppingcartPromotion shoppingcartPromotion : shoppingcartPromotions) {
			PromoRule promoRule = promoRuleManager.getById(shoppingcartPromotion.getPromoRuleId());
			promoRules.add(promoRule);
		}
		List<ShoppingcartPromotion> removeShoppingcartPromotions = new ArrayList<ShoppingcartPromotion>();
		Map<Integer,PromoRule> map = new HashMap<Integer,PromoRule>();
		List<PromoRule> promoRuleList = getPromoService().getShoppingcartPromotion(promoRules);
		for (PromoRule _promoRule : promoRuleList) {
			map.put(_promoRule.getPromoRuleId(), _promoRule);
		}
		for (ShoppingcartPromotion shoppingcartPromotion : shoppingcartPromotions) {
			if (!map.containsKey(shoppingcartPromotion.getPromoRuleId())) {
				removeShoppingcartPromotions.add(shoppingcartPromotion);
			}
		}
		shoppingcartPromotions.removeAll(removeShoppingcartPromotions);

		//----------------start:处理订单明细项----------------
		List<Integer> productSkuIdExistList = new ArrayList<Integer>();
		List<Integer> giftIdExistList = new ArrayList<Integer>();
		Set<ShoppingcartItem> cartItems	= checkoutSession.getShoppingcart().getShoppingCartItems();
		for(ShoppingcartItem cartItem: cartItems){
			OrderSku cartItemOrderSku = new OrderSku(cartItem);
			OrderSku orderSkuMatch = null; //对应的明细项
			if(cartItem.isProduct()){
				for(OrderSku orderSkuExist: salesOrder.getOrderSkus4Product()){
					if(orderSkuExist.getProductSkuId().equals(cartItemOrderSku.getProductSkuId())){
						orderSkuMatch = orderSkuExist;
						break;
					}
				}
				if(null != orderSkuMatch){
					//明细项已存在于订单
					Integer differentQuantity = cartItemOrderSku.getQuantity() - orderSkuMatch.getQuantity();
					if(differentQuantity > 0){
						//增加了数量
						//注意：分配库存
						inventoryManager.doAllocateStock4OrderAction(salesOrder,cartItemOrderSku.getProductSku(), differentQuantity);
					}else if(differentQuantity < 0){
						//减少了数量
						//注意：释放库存
						inventoryManager.doCancelAllocateStock(salesOrder,cartItemOrderSku.getProductSku(), -differentQuantity);
					}
					
					orderSkuMatch.setPrice(cartItemOrderSku.getPrice());
					orderSkuMatch.setQuantity(cartItemOrderSku.getQuantity());
					orderSkuMatch.setAllocatedQuantity(cartItemOrderSku.getAllocatedQuantity());
					orderSkuMatch.setDiscount(cartItemOrderSku.getDiscount());
					orderSkuMatch.setTax(cartItemOrderSku.getTax());
					orderSkuMatch.setTaxName(cartItemOrderSku.getTaxName());
					orderSkuMatch.setSubtotal(cartItemOrderSku.getSubtotal());
					orderSkuManager.save(orderSkuMatch);
					productSkuIdExistList.add(orderSkuMatch.getProductSkuId());
				}else{
					cartItemOrderSku.setSalesOrder(salesOrder);
					//注意：分配库存
					inventoryManager.doAllocateStock4OrderAction(salesOrder,cartItemOrderSku.getProductSku(), cartItemOrderSku.getQuantity());
					
					orderSkuManager.save(cartItemOrderSku);
					productSkuIdExistList.add(cartItemOrderSku.getProductSkuId());
				}
			}
			
			//礼品库存处理 
			if(cartItem.is_Gift()){
				for(OrderSku orderSkuExist: salesOrder.getOrderSkus4Gift()){
					if(orderSkuExist.getGift().getGiftId().equals(cartItemOrderSku.getGift().getGiftId())){
						orderSkuMatch = orderSkuExist;
						break;
					}
				}
				if(null != orderSkuMatch){
					//明细项已存在于订单
					Integer differentQuantity = cartItemOrderSku.getQuantity() - orderSkuMatch.getQuantity();
					if(differentQuantity > 0){
						//增加了数量
						//注意：分配库存
						giftManager.doAllocateGift4OrderAction(salesOrder,cartItemOrderSku.getGift(), differentQuantity);
					}else if(differentQuantity < 0){
						//减少了数量
						//注意：释放库存
						giftManager.doCanCelAllocateGift(salesOrder, cartItemOrderSku.getGift(), -differentQuantity);
					}
					//还原订单明细处理之前已释放过的礼品已分配库存
					giftManager.doCanCelAllocateGift(salesOrder,cartItemOrderSku.getGift(), -orderSkuMatch.getQuantity());
					
					orderSkuMatch.setPrice(cartItemOrderSku.getPrice());
					orderSkuMatch.setQuantity(cartItemOrderSku.getQuantity());
					orderSkuMatch.setAllocatedQuantity(cartItemOrderSku.getAllocatedQuantity());
					orderSkuMatch.setDiscount(cartItemOrderSku.getDiscount());
					orderSkuMatch.setTax(cartItemOrderSku.getTax());
					orderSkuMatch.setTaxName(cartItemOrderSku.getTaxName());
					orderSkuMatch.setSubtotal(cartItemOrderSku.getSubtotal());
					orderSkuManager.save(orderSkuMatch);
					giftIdExistList.add(orderSkuMatch.getGift().getGiftId());
				}else{
					cartItemOrderSku.setSalesOrder(salesOrder);
					//注意：分配库存
					giftManager.doAllocateGift4OrderAction(salesOrder,cartItemOrderSku.getGift(), cartItemOrderSku.getQuantity());
					orderSkuManager.save(cartItemOrderSku);
					giftIdExistList.add(cartItemOrderSku.getGift().getGiftId());
				}
			}
		}
		//删除无用的订单明细
		Iterator iterator = salesOrder.getOrderSkus().iterator();
		while(iterator.hasNext()){
			OrderSku orderSku = (OrderSku)iterator.next();
			if(orderSku.getIsProduct() && !productSkuIdExistList.contains(orderSku.getProductSkuId())){
				//注意：释放库存
				inventoryManager.doCancelAllocateStock(salesOrder,orderSku.getProductSku(), orderSku.getUnDeliveryQuantity());
				
				iterator.remove();
				orderSkuManager.deleteById(orderSku.getOrderSkuId());
			} else if(orderSku.getIs_Gift() && !giftIdExistList.contains(orderSku.getGift().getGiftId())){
				//注意：释放库存
				giftManager.doCanCelAllocateGift(salesOrder,orderSku.getGift(), orderSku.getUnDeliveryQuantity());
				
				iterator.remove();
				orderSkuManager.deleteById(orderSku.getOrderSkuId());
			}
			
		}
		//----------------end:处理订单明细项----------------
		
		//----------------start:订单促销----------------
		
		List<Integer> orderPromotionIdExistList = new ArrayList<Integer>();
		for (ShoppingcartPromotion shoppingcartPromotion : shoppingcartPromotions) {
			OrderPromotion cartOrderPromotion = new OrderPromotion(shoppingcartPromotion);
			OrderPromotion orderPromotionMatch = null; //对应的促销项
			for(OrderPromotion orderPromotionExist: (Set<OrderPromotion>)salesOrder.getOrderPromotions()){
				if(orderPromotionExist.getPromoRuleId().equals(cartOrderPromotion.getPromoRuleId())){
					orderPromotionMatch = orderPromotionExist;
					break;
				}
			}
			if(null != orderPromotionMatch){
				//明细项已存在于订单
				orderPromotionMatch.setPromotionName(cartOrderPromotion.getPromotionName());
				orderPromotionManager.save(orderPromotionMatch);
				orderPromotionIdExistList.add(orderPromotionMatch.getOrderPromotionId());
			}else{
				cartOrderPromotion.setSalesOrder(salesOrder);
				orderPromotionManager.save(cartOrderPromotion);
				orderPromotionIdExistList.add(cartOrderPromotion.getOrderPromotionId());
			}
		}
		//删除无用的订单促销
		iterator = salesOrder.getOrderPromotions().iterator();
		while(iterator.hasNext()){
			OrderPromotion orderPromotion = (OrderPromotion)iterator.next();
			if(!orderPromotionIdExistList.contains(orderPromotion.getOrderPromotionId())){
				iterator.remove();
				orderPromotionManager.deleteById(orderPromotion.getOrderPromotionId());
			}
			
		}
		//----------------end: 订单促销----------------
			
		//----------------订单日志----------------
		orderAuditHelper.doLogEditOrder(salesOrder);
		return;
	}
	
	

	/**
	 * 赠送积分
	 */
	private void doSendShopPoint(SalesOrder salesOrder,Integer shopPoint){
		//获赠积分
		Customer customer = customerManager.getByAppUserId(salesOrder.getCustomerId());
		shopPointManager.updateShopPoint(customer, shopPoint, ShopPoint.TYPE_BUY, salesOrder);
	}
	
	/**
	 * 返还全部支付积分
	 */
	private void doReturnShopPoint(SalesOrder salesOrder){
		//返还支付积分
		Customer customer = customerManager.getByAppUserId(salesOrder.getCustomerId());
		shopPointManager.updateShopPoint(customer, salesOrder.getUsedShopPoint(), ShopPoint.TYPE_PAY_RETURN, salesOrder);
	}
	
	/**
	 * 返还支付积分（后台管理员专用）
	 */
	private void doReturnShopPoint(SalesOrder salesOrder, Integer shopPoint){
		//返还支付积分
		Customer customer = customerManager.getByAppUserId(salesOrder.getCustomerId());
		shopPointManager.updateShopPoint(customer, shopPoint, ShopPoint.TYPE_PAY_RETURN, salesOrder);
	}
	
	
	/**
	 * 赠送优惠券
	 */
	private void doSendCoupon(SalesOrder salesOrder){
		EmailModel emailModel = new EmailModel();
		emailModel.setEmail(salesOrder.getCustomerEmail());
		emailModel.setFirstName(salesOrder.getCustomerFullName());
		PromoService promoService = (PromoService)ContextUtil.getSpringContext().getBean("promoService");
		promoService.doSendCoupon(salesOrder.getGainedCouponTypeId(), emailModel);
	}
	
	/**
	 * 返还支付的礼券金额
	 */
	private void doReturnGiftCertificateMoney(SalesOrder salesOrder,OrderCancelModel cancelModel){
		for(OrderPayment orderPayment:salesOrder.getOrderPayments4Pay()){
			if(orderPayment.getPaymentMethodId().equals(OrderConstants.PAYMENT_METHOD_GC) && StringUtils.isNotBlank(orderPayment.getGiftCertificateNo())){
				giftCertificateManager.doReturnGiftCertificate(orderPayment.getGiftCertificateNo(), orderPayment.getPaymentAmount());
				cancelModel.getGiftCertificateMoneyList().add(orderPayment.getPaymentAmount());
				cancelModel.getGiftCertificateNoList().add(orderPayment.getGiftCertificateNo());
			}
		}
	}
	
	/**
	 * 返还支付的礼券金额（管理员专用）
	 */
	private void doReturnGiftCertificateMoney4Admin(SalesOrder salesOrder,OrderCancelModel cancelModel){
		if(!ArrayUtils.isEmpty(cancelModel.getGiftCertificateNos())){
			List<OrderPayment> orderPaymentList = salesOrder.getGiftCertificateOrderPayments4Pay(); 
			for(int i=0; i< cancelModel.getGiftCertificateNos().length; i++){
				Short returnGiftCertificateNo = cancelModel.getReturnGiftCertificates()[i];
				if(Constants.FLAG_TRUE.equals(returnGiftCertificateNo)){
					//case：确认返还
					BigDecimal giftCertificateMoney = cancelModel.getGiftCertificateMoneys()[i];
					if(giftCertificateMoney.compareTo(BigDecimal.ZERO) > 0){
						//case:返还金额>0
						String giftCertificateNo = cancelModel.getGiftCertificateNos()[i];
						for(OrderPayment orderPayment: orderPaymentList){
							if(orderPayment.getGiftCertificateNo().equals(giftCertificateNo)){
								//case：找到支付项
								if(orderPayment.getPaymentAmount().compareTo(giftCertificateMoney) >= 0){
									//case:必须在限额内(服务端验证)	
									giftCertificateManager.doReturnGiftCertificate(orderPayment.getGiftCertificateNo(), giftCertificateMoney);
									cancelModel.getGiftCertificateMoneyList().add(giftCertificateMoney);
									cancelModel.getGiftCertificateNoList().add(giftCertificateNo);
								}
							}
						}
					}
				}
				
			}
		}
	}
	
	
	
	
}
